
/* --------------------------------------
 * Copyright 2008 Jean-Matthieu BARBIER
 * --------------------------------------
 * This file is part of QLocatePC.
 *
 * QLocatePC is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * QLocatePC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with QLocatePC.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "httplocate.h"
#include "setup.h"
#include <QObject>
#include <QtNetwork>

/**
 * Constructor. Prepares http QHttp and timer QTimer objects for 
 * communication. Loads default settings. Does not start timer.
 */
QLocatePCHttpLocate::QLocatePCHttpLocate(QObject *parent)
 : QObject(parent) {
  http = new QHttp(this);
  timer = new QTimer(this);
  QLocatePCSetupData settings;
  settings.load();
  daemonrunning = settings.daemon;
  daemoninterval = 0;
  connect(timer,SIGNAL(timeout()), this, SLOT(daemonCycle()));
  connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&)),
          this, SLOT(responseReceived(const QHttpResponseHeader&)));
  connect(http, SIGNAL(done(bool)),
          this, SLOT(httpDone(bool)));
}

/**
 * Responds to daemon update request. Launches a daemon Cycle.
 */
void QLocatePCHttpLocate::updateDaemon() {
  daemonCycle();
}


/**
 * Daemon main loop : updates daemon data and launches goLocate.
 * Emitted signals : daemonKilled() + all http responses
 */
void QLocatePCHttpLocate::daemonCycle() {
  QLocatePCSetupData settings;
  settings.load();
  if(this->daemonrunning && !settings.daemon) {
    //- Warns : daemon have been killed
    emit daemonKilled();
  }
  this->daemonrunning = settings.daemon;
  if(this->daemonrunning && (this->daemoninterval != settings.daemoninterval)) {
    //- Updates timer interval
    this->daemoninterval = settings.daemoninterval;
    this->timer->start(this->daemoninterval);
  }
  if(this->daemonrunning) {
    this->goLocate(&settings, QLocatePCHttpLocate::actionLocate);    
  }
}


/**
 * HTTP Response received.
 * Re-emits correct signal (locSuccess or locFailed) depending on header status code.
 */
void QLocatePCHttpLocate::responseReceived(const QHttpResponseHeader& resp) {
  if(resp.statusCode()==200)
    emit locSuccess("HEADER-OK");
  else
    emit locFailed(resp.reasonPhrase());
}

/**
 * HTTP Last request done.
 */
void QLocatePCHttpLocate::httpDone(bool status = true) {
  if(!status)
    emit locSuccess("HTTP-OK");
  else
    emit locFailed(http->errorString());
}

/**
 * Creates URL from settings and mode.
 * @returns bool True if url is valid.
 * @params settings Settings used to compose url
 * @params url Returned url
 * @param mode Mode used.
 */
bool QLocatePCHttpLocate::makeUrl(const QLocatePCSetupData* settings, QUrl* url, const int mode) {
  url->setUrl(settings->url); 
  url->addQueryItem("LID",settings->identifier);
  url->addQueryItem("LNM",settings->computername);
  switch(mode) {
    case actionLocate:
      url->addQueryItem("ACT","locate");
      break;
    case actionSetup:
      url->addQueryItem("ACT","setup");
      url->addQueryItem("NFO",settings->moreinfo);
      break;
    default:
      url->addQueryItem("ACT","ask");
      break;
  }
  return url->isValid(); 
}

void QLocatePCHttpLocate::goSilentLocate() {
  QLocatePCSetupData settings;
  settings.load();
  this->goLocate(&settings, QLocatePCHttpLocate::actionLocate);
}

int QLocatePCHttpLocate::goLocate(QLocatePCSetupData* settings, int mode)
{
  QUrl url;
  makeUrl(settings, &url, mode);
  QHttpRequestHeader req("GET",url.encodedPath());
  http->setHost(url.host());
  http->get(url.toEncoded());
  return 0;
}


